<!DOCTYPE html>
<html>
<head>
    <title>wedesk 网页控制端</title>

    <!--    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>-->
    <!--    <link rel="stylesheet" href="https://unpkg.com/element-ui@1.4/lib/theme-default/index.css">-->
    <!--    <script src="https://unpkg.com/element-ui@1.4/lib/index.js"></script>-->
    <!--    <script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>-->
    <!--    <script src="https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.18.0/js/md5.js"></script>-->
    <!--    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>-->
    <!--    <script src="https://cdn.bootcdn.net/ajax/libs/pako/2.0.4/pako.es5.js"></script>-->
    <!--    <script src="https://cdn.jsdelivr.net/npm/js-base64@3.7.2/base64.min.js"></script>-->



    <script src="js/vue.min.js"></script>
    <link rel="stylesheet" href="js/index.css">
    <script src="js/index.js"></script>
    <script src="js/crypto-js.min.js"></script>
    <script src="js/md5.js"></script>
    <script src="js/jquery.js"></script>
    <script src="js/pako.es5.js"></script>
    <script src="js/base64.min.js"></script>


</head>
<body>

<!-- 2. 定义应用的根元素 -->
<div id="app">
    <div>
        <h1><a href="https://gitee.com/dahuoyzs/open-wedesk" target="_blank">wedesk</a></h1>
        <el-row :gutter="20">
            <el-col :span="24">
                状态: <el-tag :type="statusType">{{statusText}}</el-tag>
                <el-input v-model="ipPort" style="width: 140px" width="140" placeholder="127.0.0.1:54321" ></el-input>
                <el-button v-if="status===0"  @click="connect">连接</el-button>
                <el-button v-if="status!==0" @click="close">断开</el-button>
                <el-input v-if="status!==0" v-model="password" style="width: 200px" type="password" placeholder="Please input password" show-password ></el-input>
                <el-button v-if="status!==0" @click="auth">认证</el-button>

                <span style="color: #13ce66">
          同步次数: <el-tag type="info">{{syncNum}}</el-tag>
          ↓:<el-tag type="info">{{this.byteSize(syncLastSize)}}</el-tag>
          累计 :<el-tag type="info">{{this.byteSize(syncTotalSize)}}</el-tag>
        </span>
                <!--        <el-button v-if="status!==0" @click="rgbToInt(0,0,0,255)">测试rgb方法</el-button>-->

            </el-col>

            <el-col :span="24">
                <el-table :data="pcInfos" style="width: 100%" >
                    <el-table-column v-show="false" v-if="false" fixed prop="cid" label="cid" width="400" ></el-table-column>
                    <el-table-column prop="userName" label="userName" width="100" ></el-table-column>
                    <el-table-column prop="processor" label="processor" width="250" ></el-table-column>
                    <el-table-column prop="memory" label="memory" width="250" ></el-table-column>
                    <el-table-column show-overflow-tooltip prop="diskList" label="diskList" width="250" ></el-table-column>
                    <el-table-column prop="osArch" label="osArch" width="80" ></el-table-column>
                    <el-table-column prop="osName" label="osName" width="80"></el-table-column>
                    <el-table-column prop="userCountry" label="userCountry" width="100" ></el-table-column>
                    <el-table-column prop="hostName" label="hostName" width="100"></el-table-column>
                    <el-table-column prop="userCurrDir" label="userCurrDir" width="200" ></el-table-column>
                    <el-table-column prop="userTempDir" label="userTempDir" width="150" ></el-table-column>
                    <el-table-column prop="macAddress" label="macAddress" width="100" ></el-table-column>
                    <el-table-column prop="userHomeDir" label="userHomeDir" width="150" ></el-table-column>
                    <el-table-column fixed="right" label="Operations" width="200">
                        <template slot-scope="scope">
                            <el-button type="primary" size="small"  @click="onWatchBtn(scope.row)">
                                观看
                            </el-button>
                            <el-button type="primary" size="small"  @click="onCtrlBtn(scope.row)">
                                控制
                            </el-button>
                            <el-button type="primary" size="small" @click="ctrlClose(scope.row)">
                                结束
                            </el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-col>
            <!--      v-show="status > 3"-->
            <div >
                <!-- 工具栏 -->
                <el-col :span="24">
                    <el-button @click="toggleFullScreen">全屏</el-button>
                    <el-radio-group v-model="radioModel" size="medium" @change="onRadioGroupChange">
                        <el-radio-button label="原始比例" >原始比例</el-radio-button>
                        <el-radio-button label="自适应">自适应</el-radio-button>
                    </el-radio-group>
                    <el-select v-model="curRatio" placeholder="分辨率" size="large" style="width: 180px" @change="onRatioChange">
                        <el-option v-for="item in ratioOptions" :key="item" :label="item" :value="item"></el-option>
                    </el-select>
                </el-col>
                <!-- 展示区域 style="display: flex;justify-content: center;align-items: center;"
                style="position: absolute;top:0;bottom:0;left: 0; right:0;margin: auto;"
                -->
                <!-- 惊了，keydown只有聚焦在键盘输入区时才有效，无法输入内容的元素怎么监听键盘按下的事件？全局按键事件你应该绑定在window或者document上，-->
                <el-col :span="24" v-show="status > 3">
                    <div ref="showDiv" :style="showDivStyle" >
                        <canvas ref="canvas"
                                :style="canvasStyle"
                                :width="canvasWidth" :height="canvasHeight" @contextmenu.prevent="rightClick"
                                @mousedown="handleMouseDown" @mousemove="handleMouseMove" @mouseup="handleMouseUp"
                                @wheel="handleWheel"
                        ></canvas>
                    </div>

                </el-col>
            </div>


        </el-row>

    </div>

</div>
<!--import CryptoJS from 'crypto-js';-->
<!--import pako from 'pako';-->
<script>

    // 3. 创建Vue实例并挂载到id为app的元素上
    new Vue({
        el: '#app',
        data: {
            ipPort:'127.0.0.1:54321',
            socket: null,
            status: 0,  //0未连接，1已连接，2已认证,3认证失败
            statusType:'info',
            password:'dahuoyzs',//服务器要校验   AuthUtil.getPassword(),//'dahuoyzs',//sale wedesk
            toCid:'',//当前控制的cid
            syncNum: 0,
            syncLastSize: 0,
            syncTotalSize: 0,
            pcInfos: [],
            radioModel:'原始比例', //原始比例||自适应
            ratioOptions: [
                '800 x 600',
                '1024 x 768',
                '1280 x 720(720P)',
                '1280 x 800',
                '1366 x 768(18.5寸)',
                '1440 x 900',
                '1600 x 1200',
                '1920 x 1080(1080P)',
                '1920 x 1200',
                '2560 x 1440(2K)',
                '2560 x 1440',
                '3840 x 2160(4K)',
            ],
            // curRatio: '1280 x 720(720P)',
            // curRatio: '1440 x 900',
            curRatio: '1920 x 1080(1080P)',
            showDivWidth: 1440,
            showDivHeight: 900,
            imgWidth: 1440,
            imgHeight: 900,
            canvasWidth: 1440,
            canvasHeight: 900,
            showDivStyle:{
                backgroundColor: "#000000",
                width: '1440px',
                height: '900px',
                overflow: 'auto',//滚动条
                margin: '0 auto',
                // textAlign: 'center',
                position: 'relative'
                // display: 'flex',
                // justifyContent: 'center',
                // alignItems: 'center',
            },
            canvasStyle:{
                position: 'absolute',
                left: '0',
                top: '0',
                margin: 'auto'
            },
            mouse: {
                x: 0,
                y: 0,
                down: false,
                move: false,
                wheel: 0,
                wheelTimer: null,
                wheelTime: 100,
            },
            lastBytes: null,
            imageData: null,
            canvas: null,
            scale:1,
            offsetX:0,
            offsetY:0,
            frames: [],
            keyboard:[],//缓存按下了哪些按键，blur失去焦点时，全部同步释放
            testStr: '',
            ctrlType:0,    //1观看2控制
            xxxx:0
        },
        methods: {
            connect() {
                let that = this;
                that.syncNum = 0
                that.syncLastSize = 0
                that.syncTotalSize = 0
                let webSocketUrl = 'ws://'+this.ipPort+'/wedesk/websocket'
                that.socket = new WebSocket(webSocketUrl);
                that.socket.onopen = () => {
                    that.status = 1;
                    that.statusType = 'warning'
                    console.log(webSocketUrl+"连接成功");
                    that.socket.send(JSON.stringify({ cmd:50, obj: that.webInfo() }));
                };

                this.socket.onmessage = (event) => {
                    if (event.data instanceof ArrayBuffer) {
                        that.calcSize(event.data.byteLength)
                        // console.log('ArrayBuffer byte size:', event.data.byteLength,that.byteSize(event.data.byteLength))
                        let bytes = new Uint8Array(event.data);
                        let cmd = that.uint8GetInt(bytes, 0)
                        that.imgWidth= that.uint8GetInt(bytes, 8)
                        that.imgHeight = that.uint8GetInt(bytes, 12)
                        if (cmd === 33) {
                            that.status = 4
                            that.frames.push(bytes)
                            that.timer = setTimeout(() => {that.showImg()
                            },50);
                        }
                    } else if (typeof event.data === 'string' || event.data instanceof String) {
                        //console.log('str len:' + event.data.length)
                        console.log(event.data)
                        let protocol = JSON.parse(event.data)
                        if (protocol.cmd === 1001) {//授权协议返回状态值
                            that.authRes(protocol)
                        } else {
                            console.error('未知的协议:' + event.data)
                        }
                    } else {
                        console.error("未知的数据格式")
                    }

                };
                that.socket.onerror = (error) => {
                    console.error('错误:', error);
                };
                that.socket.onclose = (event) => {
                    that.isConnected = false;
                    that.status = 0;
                    console.log(`断开: ${event.reason}`);
                };
                that.socket.binaryType = 'arraybuffer';
            },
            showImg(){
                let that = this;
                // console.log('挤压长度:',that.frames.length)
                let bytes = that.frames.shift()
                if (bytes && this.$refs.canvas){
                    that.canvas = this.$refs.canvas.getContext('2d');
                    if (that.radioModel === '原始比例'){
                        //远程图片和本地画板大小不一样。以远程图片为准
                        if (that.imageData === null || that.canvasWidth!==that.imgWidth || that.canvasHeight!==that.imgHeight) {
                            that.canvasWidth = that.imgWidth;
                            that.canvasHeight = that.imgHeight;
                            console.log("重新创建imageData")
                            that.imageData = that.canvas.createImageData(that.imgWidth, that.imgHeight);
                        }
                        that.decompress(bytes, that.imageData)
                        that.canvas.putImageData(that.imageData, 0, 0);
                    } else if (that.radioModel === '自适应') {
                        // //本地画板和展示框大小不一样。以展示框大小为准
                        // if (that.imgWidth === that.showDivWidth && that.imgWidth === that.showDivWidth) {
                        //   if (that.imageData === null) {
                        //     that.imageData = that.canvas.createImageData(that.showDivWidth, that.showDivHeight)
                        //   }
                        //   that.decompress(bytes, that.imageData)
                        //   that.canvas.putImageData(that.imageData, 0, 0)
                        //   console.log('宽高一样')
                        // } else {
                        //   // console.log("imgWidth:", that.imgWidth, "imgHeight:", that.imgHeight, "showDivWidth:", that.showDivWidth, "showDivHeight:", that.showDivHeight)
                        //
                        // }

                        let srcImgData = new ImageData(that.imgWidth, that.imgHeight)
                        that.decompress(bytes, srcImgData)
                        that.canvasWidth = that.showDivWidth;
                        that.canvasHeight = that.showDivHeight;
                        if (that.imageData === null) {
                            that.imageData = that.canvas.createImageData(that.showDivWidth, that.showDivHeight)
                            that.imageData = that.upSampleImageData(srcImgData, that.showDivWidth, that.showDivHeight)
                            // that.canvas.putImageData(that.imageData, 0, 0)
                        } else {
                            //本行的作用是，当画板大小改变时，自动变换上一次的画板大小
                            that.imageData = that.upSampleImageData(that.imageData, that.showDivWidth, that.showDivHeight)
                            let diffImgData = that.upSampleImageData(srcImgData, that.showDivWidth, that.showDivHeight)
                            for (let i = 0; i < that.imageData.data.length; i++) {
                                if (diffImgData.data[i]!==0 && diffImgData.data[i]!==255){
                                    that.imageData.data[i] = diffImgData.data[i]
                                }
                            }
                        }
                        that.canvas.putImageData(that.imageData, 0, 0)
                        that.timer = setTimeout(() => {that.showImg()
                        },50);
                    }
                }
            },
            //上采样
            upSampleImageData(imgData, newWidth, newHeight) {
                if (imgData.width === newWidth && imgData.height === newHeight){
                    return imgData;
                }
                // let start = new Date().getTime()
                const oldWidth = imgData.width;
                const oldHeight = imgData.height;
                const newImgData = new ImageData(newWidth, newHeight);
                for (let y = 0; y < newHeight; y++) {
                    for (let x = 0; x < newWidth; x++) {
                        const sourceX = Math.floor(x * oldWidth / newWidth);
                        const sourceY = Math.floor(y * oldHeight / newHeight);
                        const sourceIndex = (sourceY * oldWidth + sourceX) * 4;
                        const targetIndex = (y * newWidth + x) * 4;
                        newImgData.data[targetIndex] = imgData.data[sourceIndex];
                        newImgData.data[targetIndex + 1] = imgData.data[sourceIndex + 1];
                        newImgData.data[targetIndex + 2] = imgData.data[sourceIndex + 2];
                        newImgData.data[targetIndex + 3] = imgData.data[sourceIndex + 3];
                    }
                }
                // let end = new Date().getTime()
                // console.log(this.showDivWidth,this.showDivHeight,',upSampleImageData耗时:', (end - start))
                return newImgData;
            },
            webInfo(){
                return  {
                    userAgent: navigator.userAgent,
                    width: window.screen.width,
                    height:window.screen.height,
                    availWidth:window.screen.availWidth,
                    availHeight:window.screen.availHeight,
                    isExtended:window.screen.isExtended
                }
            },
            uint8GetInt(uint8Array, offset) {
                let dataView = new DataView(uint8Array.buffer)
                return dataView.getInt32(offset)
            },
            byteSize(len) {
                let byteNum = 1024;
                if (len < byteNum) {
                    return len + 'B';
                } else if (len < Math.pow(byteNum, 2)) {
                    return (len / Math.pow(byteNum, 1)).toFixed(2) + 'KB';
                } else if (len < Math.pow(byteNum, 3)) {
                    return (len / Math.pow(byteNum, 2)).toFixed(2) + 'MB';
                } else if (len < Math.pow(byteNum, 4)) {
                    return (len / Math.pow(byteNum, 3)).toFixed(2) + 'GB';
                } else {
                    return (len / Math.pow(byteNum, 4)).toFixed(2) + 'TB';
                }
            },
            calcSize(len){
                this.syncNum++;
                this.syncLastSize = len
                this.syncTotalSize += len
            },
            md5(password,salt){
                const md5_one = md5(password + salt)
                const md5_two = md5(md5_one + salt)
                const md5_three = md5(md5_two + salt)
                return md5_three
            },
            auth(){
                if (this.password) {
                    let authStr = this.md5(this.password, 'wedesk')
                    let authReq = { cmd:1001, obj:{ authStr: authStr } }//授权
                    this.sendMessage(JSON.stringify(authReq));
                }
            },
            authRes(protocol){
                if (protocol.type !== 21) {//type=21成功拿到pcInfo信息
                    this.pcInfos = protocol.obj
                    this.status = 2;
                    this.statusType = 'success'
                }else {//错误
                    console.error(protocol.obj)
                    this.status = 3;
                    this.statusType = 'danger'
                }
            },
            onWatchBtn(row) {
                this.ctrlType = 1;
                this.ctrlOpen(row);
            },

            onCtrlBtn(row) {
                this.ctrlType = 2;
                this.ctrlOpen(row);
            },
            onCloseBtn(row) {
                this.ctrlType = 0;
                this.ctrlClose(row);
            },
            ctrlOpen(row){
                if (this.status > 3 && this.toCid) {
                    let ctrl = { cmd:32, obj:{ toCid: this.toCid } }//关
                    this.sendMessage(JSON.stringify(ctrl));
                }
                this.lastBytes = null;
                this.imageData = null;
                let ctrl = { cmd: 31, obj: { toCid: row.cid } }//开
                this.sendMessage(JSON.stringify(ctrl));
                this.toCid = row.cid
            },
            ctrlClose(row){
                this.lastBytes = null;
                this.imageData = null;
                this.toCid = null;
                let ctrl = { cmd:32, obj:{ toCid:row.cid } }//关
                this.sendMessage(JSON.stringify(ctrl));
                this.status = 2
            },
            close(){
                if (this.socket) {
                    this.isConnected = false;
                    this.status = 0;
                    this.socket.close();
                }
            },
            // 你可以添加其他方法来发送消息到 WebSocket 服务器
            sendMessage(message) {
                if (this.socket.readyState === WebSocket.OPEN) {
                    this.socket.send(message);
                }
            },
            toggleFullScreen() {
                if (!document.fullscreenElement) {
                    this.enterFullScreen();
                } else {
                    this.exitFullScreen();
                }
            },
            enterFullScreen() {
                let element = this.$refs.showDiv;
                if (element.requestFullscreen) {
                    element.requestFullscreen();
                } else if (element.mozRequestFullScreen) { /* Firefox */
                    element.mozRequestFullScreen();
                } else if (element.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
                    element.webkitRequestFullscreen();
                } else if (element.msRequestFullscreen) { /* IE/Edge */
                    element.msRequestFullscreen();
                }
            },
            exitFullScreen() {
                if (document.exitFullscreen) {
                    document.exitFullscreen();
                } else if (document.mozCancelFullScreen) { /* Firefox */
                    document.mozCancelFullScreen();
                } else if (document.webkitExitFullscreen) { /* Chrome, Safari and Opera */
                    document.webkitExitFullscreen();
                } else if (document.msExitFullscreen) { /* IE/Edge */
                    document.msExitFullscreen();
                }
            },
            buildMouseEvent(event){
                let x = event.offsetX;
                let y = event.offsetY;
                if (this.radioModel === '自适应') {
                    let widthRatio = this.showDivWidth / this.imgWidth
                    let heightRatio = this.showDivHeight / this.imgHeight
                    x = Math.floor(event.offsetX/widthRatio);
                    y = Math.floor(event.offsetY/heightRatio);
                    // console.log(event.offsetX, event.offsetY, x, y)
                }
                return {
                    cmd:35,
                    obj:{
                        toCid:this.toCid,
                        type:event.type,
                        which:event.which,
                        x:x,
                        y:y,
                        deltaY:event.deltaY,
                        timestamp : parseInt(event.timeStamp)
                    }
                };
            },
            handleMouseDown(event) {
                if (this.toCid && this.ctrlType === 2) {
                    let mouseEvent = this.buildMouseEvent(event)
                    // console.log(mouseEvent)
                    this.sendMessage(JSON.stringify(mouseEvent));
                    event.preventDefault();//阻止事件
                }
            },
            handleMouseMove(event) {
                if (this.toCid && this.ctrlType === 2) {
                    let mouseEvent = this.buildMouseEvent(event)
                    this.sendMessage(JSON.stringify(mouseEvent));
                    event.preventDefault();//阻止事件
                }
            },
            handleMouseUp(event) {
                if (this.toCid && this.ctrlType === 2) {
                    let mouseEvent = this.buildMouseEvent(event)
                    this.sendMessage(JSON.stringify(mouseEvent));
                    event.preventDefault();//阻止事件
                }
            },
            handleWheel(event) {
                if (this.toCid && this.ctrlType === 2) {
                    let mouseEvent = this.buildMouseEvent(event)
                    this.sendMessage(JSON.stringify(mouseEvent));
                    event.preventDefault();//阻止事件
                }
            },
            buildKeyboardEvent(event){
                return {
                    cmd:36,
                    obj:{
                        toCid:this.toCid,
                        type:event.type,
                        keyCode:event.keyCode,
                        timestamp : parseInt(event.timeStamp)
                    }
                };
            },
            handleKeyDown(event) {
                if (this.toCid && this.ctrlType === 2) {
                    this.keyboard[event.keyCode] = true
                    let keyboardEvent = this.buildKeyboardEvent(event)
                    // console.log(keyboardEvent)
                    this.sendMessage(JSON.stringify(keyboardEvent));
                    // event.preventDefault();//阻止事件
                }
            },
            handleKeyUp(event) {
                if (this.toCid && this.ctrlType === 2) {
                    this.keyboard[event.keyCode] = false;
                    let keyPack = this.buildKeyboardEvent(event)
                    // console.log(keyPack)
                    this.sendMessage(JSON.stringify(keyPack));
                    // event.preventDefault();//阻止事件
                }
            },
            handleKeyBlur(event){
                if (this.toCid && this.ctrlType === 2) {
                    for (let i = 0; i < this.keyboard.length; i++) {
                        if (this.keyboard[i]) {
                            let keyPack = {
                                cmd:36,
                                obj:{
                                    toCid:this.toCid,
                                    type:'keyup',
                                    keyCode:i,
                                    timestamp : parseInt(event.timeStamp)
                                }
                            }
                            this.sendMessage(JSON.stringify(keyPack));
                        }
                    }
                }
            },
            fullscreenChange(){
                if (document.fullscreenElement) {
                    // console.log("全屏")
                    this.showDivWidth = window.screen.width
                    this.showDivHeight = window.screen.height
                    this.showSizeChg()
                    console.log("全屏",this.showDivWidth,this.showDivHeight)
                }else {
                    // console.log("退出全屏")
                    if (this.curRatio.indexOf(' x ') > 0){
                        let strings = this.curRatio.split("x")
                        let widthStr = strings[0].replace(/^\s*/, "")
                        let heightStr = strings[1].replace(/^\s*/, "")
                        this.showDivWidth = parseInt(widthStr)
                        this.showDivHeight = parseInt(heightStr)
                        this.showSizeChg()
                        console.log("退出全屏",this.showDivWidth,this.showDivHeight)
                    }
                }
            },
            onRatioChange(newRatio){
                if (this.curRatio.indexOf(' x ') > 0){
                    let strings = this.curRatio.split("x")
                    let widthStr = strings[0].replace(/^\s*/, "")
                    let heightStr = strings[1].replace(/^\s*/, "")
                    this.showDivWidth = parseInt(widthStr)
                    this.showDivHeight = parseInt(heightStr) //js里的 parseInt('768(18.5寸)') 可以把768拿出来，而不报错
                    this.showSizeChg()
                    console.log("尺寸变化",this.showDivWidth,this.showDivHeight)
                }
            },
            showSizeChg(){
                let that = this
                this.showDivStyle.width = this.showDivWidth + 'px'
                this.showDivStyle.height = this.showDivHeight + 'px'
                if (that.showDivWidth > that.canvasWidth || that.showDivHeight > that.canvasHeight) {
                    // console.log("装得下，居中")
                    that.canvasStyle.bottom = 0
                    that.canvasStyle.right = 0
                } else {
                    // console.log("装不下,左上角")
                    that.canvasStyle.bottom = 'auto'
                    that.canvasStyle.right = 'auto'
                }
                if (that.radioModel === '自适应' && that.status > 2) {
                    // console.log('自适应,重新打开控制协议')
                    that.lastBytes = null
                    // that.imageData = null
                    let ctrl = { cmd: 31, obj: { toCid: that.toCid } }//开
                    this.sendMessage(JSON.stringify(ctrl))
                }
            },
            onRadioGroupChange(newRatioModel){
                console.log(newRatioModel)
            },
            rightClick(){
                console.log("canvas拒绝右键点击")
            },
            func5(){

            },
            decompress(compressedData, imageData) {
                // 行程编码解码
                var headerLength = 16;
                for (var i = (compressedData[headerLength] & 0xff) * 3 + 1 + headerLength, k = 0; i < compressedData.length; )
                {
                    var rl = (((compressedData[i] & 0xff) << 8) | (compressedData[i + 1] & 0xff)) & 0xffff
                    var times = rl & 0x7fff;
                    var red, green, blue;
                    if ((rl & 0x8000) > 0)
                    {
                        var index = compressedData[i + 2] & 0xff;
                        if (index == 0)
                        {
                            k += times * 4;
                            i += 3;
                            continue;
                        }
                        var index = (index - 1) * 3 + 1 + headerLength;
                        red = compressedData[index] & 0xff;
                        green = compressedData[index + 1] & 0xff;
                        blue = compressedData[index + 2] & 0xff;
                        i += 3;
                    }
                    else
                    {
                        red = compressedData[i + 2] & 0xff;
                        green = compressedData[i + 3] & 0xff;
                        blue = compressedData[i + 4] & 0xff;
                        i += 5;
                    }

                    for (var s = 0; s < times; s++)
                    {
                        imageData.data[k++] = red;
                        imageData.data[k++] = green;
                        imageData.data[k++] = blue;
                        imageData.data[k++] = 0xff;
                    }
                }
            }
        },
        computed:{
            statusText(){
                if (this.status === 0) {
                    return '0未连接'
                } else if (this.status === 1) {
                    return '1已连接未认证'
                } else if (this.status === 2) {
                    return '2已认证'
                } else if (this.status === 3) {
                    return '3认证失败'
                } else if (this.status === 4) {
                    return '4连接中'
                }
            }
        },
        mounted() {
            window.addEventListener('keydown', this.handleKeyDown);
            window.addEventListener('keyup', this.handleKeyUp);
            window.addEventListener('blur', this.handleKeyBlur);
            document.addEventListener('fullscreenchange', this.fullscreenChange);
        },
        created() {
            //Blob、ArrayBuffer和Buffer：二进制数据处理: https://juejin.cn/post/7242373876089225274
            //javascript（js）语法 将blob转arrayBuffer、arrayBuffer转Uint8Array、Uint8Array转String的方法 https://blog.csdn.net/JCjunior/article/details/128705889
            this.connect()
        }
    });
</script>

</body>
</html>